/**
 *
 */
package edu.towson.cosc.cosc455.kchmura.compiler;

import edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer;

/**
 * @author kchmur1
 * This class contains the methods to analyze the input against the BNF
 * grammar for LOLCODE for specific tags or text.
 */
public class MySyntaxAnalyzer implements SyntaxAnalyzer {

    static boolean docBeginFlag = false;

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#lolcode()
     */
    @Override
    public void lolcode() {

        if (!compiler.token.equalsIgnoreCase(LexicalTokens.DOC_BEGIN) && (docBeginFlag == false)) {
            System.err.println("Syntax Error: " + compiler.token + "when " + LexicalTokens.DOC_BEGIN + "was expected.");
            System.exit(0);
        }
        if (compiler.token.equalsIgnoreCase(LexicalTokens.DOC_BEGIN) && (docBeginFlag == false)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            docBeginFlag = true;
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.DOC_END)) {
            compiler.addToArrayMethod(compiler.token);
        } else if (!compiler.token.equalsIgnoreCase(LexicalTokens.DOC_END)) {
            System.err.println("Syntax Error: " + compiler.token + "when " + LexicalTokens.DOC_END + "was expected.");
            System.exit(0);
        } else {
            comment();
            head();
            title();
            body();
        }



    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#comment()
     */
    @Override
    public void comment() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }


    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#head()
     */
    @Override
    public void head() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.HEAD_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            title();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.HEAD_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#title()
     */
    @Override
    public void title() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.TITLE_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.TITLE_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#paragraph()
     */
    @Override
    public void paragraph() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.PARAGRAPH_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            bold();
            italics();
            list();
            text();
            newline();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.PARAGRAPH_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#bold()
     */
    @Override
    public void bold() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.BOLD_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#italics()
     */
    @Override
    public void italics() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#list()
     */
    @Override
    public void list() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            item();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.LIST_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }


    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#item()
     */
    @Override
    public void item() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.ITEM_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.ITEM_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#audio()
     */
    @Override
    public void audio() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#video()
     */
    @Override
    public void video() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_BEGIN)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#define()
     */
    @Override
    public void define() {
        {
            if (compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_BEGIN)) {
                compiler.addToArrayMethod(compiler.token);
                compiler.lexer.getNextToken();
                text();
            } else if (compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_VALUE)) {
                compiler.addToArrayMethod(compiler.token);
                compiler.lexer.getNextToken();
                text();
            } else if (compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_END)) {
                compiler.addToArrayMethod(compiler.token);
                compiler.lexer.getNextToken();
            } else {
                compiler.lexer.getNextToken(); 
            }
        }
    }

    /*
     * (non-Javadoc) @see
     * edu.towson.cosc.cosc455.interfaces.SyntaxAnalyzer#use()
     */
    @Override
    public void use() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_VISIBLE)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
            text();
        } else if (compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_END)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        } else {
            compiler.lexer.getNextToken(); 
        }
    }

    /**
     * This method checks for text or other types allowed in inner text sections of the BNF.
     */
    public void text() {
        if(compiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)){
            newline();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.SOUNDS_BEGIN)){
            audio();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.VIDEO_BEGIN)){
            video();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.VARIABLE_BEGIN)){
            use();
        }
        else{
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        }
    }

    /**
     * This method checks for a newline token.
     */
    public void newline() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.NEWLINE)) {
            compiler.addToArrayMethod(compiler.token);
            compiler.lexer.getNextToken();
        }
    }

    /**
     * This method checks for all types allowed in the BNF body section.
     */
    public void body() {
        if (compiler.token.equalsIgnoreCase(LexicalTokens.COMMENT_BEGIN)){
            comment();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.PARAGRAPH_BEGIN)){
            paragraph();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.BOLD_BEGIN)){
            bold();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.ITALICS_BEGIN)){
            italics();
        }
        else if(compiler.token.equalsIgnoreCase(LexicalTokens.LIST_BEGIN)){
            list();
        }
        else{
            text();
        }
    }
}
